home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 27 / CU Amiga Magazine's Super CD-ROM 27 (1998)(EMAP Images)(GB)[!][issue 1998-10].iso / CUCD / Programming / Yaroze / UploadSrc / serial.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-07-24  |  8.7 KB  |  343 lines

  1. /*
  2.  * NAME
  3.  *   serial.c - 17-May-97 00:24:35
  4.  *
  5.  * AUTHOR
  6.  *   Jon Rocatis - jon@funcom.com
  7.  *
  8.  * DESCRIPTION
  9.  *   Contains functions for controlling the serial device
  10.  *
  11.  */
  12.  
  13. #include <ctype.h>
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <exec/types.h>
  17. #include <devices/serial.h>
  18. #include <proto/all.h>
  19. #include <time.h>
  20. #include <string.h>
  21.  
  22. #include "upload_protos.h"
  23. #include "serial_protos.h"
  24. #include "myecoff.h"
  25. #include "upload.h"
  26.  
  27. //#define DEBUGSEND
  28.  
  29. #define DEVICE_NAME "serial.device"
  30. //#define UNIT_NUMBER 0
  31.  
  32. //#define DEVICE_NAME "BaudBandit.device"
  33. #define UNIT_NUMBER 0
  34.  
  35. #define BUFSIZE 16384       // Size of ring buffer for incoming bytes from serial
  36. #define STACK_SIZE 2048     // Stack size for the serial-reader task
  37.  
  38. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  39.  
  40. struct MsgPort  *SerialMPread;
  41. struct MsgPort  *SerialMPwrite;
  42. struct IOExtSer *SerialIOread;
  43. struct IOExtSer *SerialIOwrite;
  44.  
  45. UBYTE buffer[BUFSIZE];      // Buffer for incoming bytes from serial interface
  46. volatile UBYTE incoming;    // The incoming byte from the serial interface
  47. BOOL w4bin;                 // Wait for "binary"
  48. BOOL w4y;                   // Wait for 'Y'
  49.  
  50. struct Task *task;          // Our task for reading the serial device
  51. struct Task *mainTask;      // Ptr to main task
  52.  
  53. static LONG bufIdx;
  54. static LONG lineIdx;        // Start of line index
  55. static LONG stopIdx;
  56.  
  57. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  58.  
  59. void PrintLine()
  60. {
  61.   LONG idx;
  62.   LONG _stopIdx = stopIdx;       // Cache this shared var (ugly!)
  63.     
  64.     for ( idx = lineIdx; idx != _stopIdx; )
  65.     {
  66.       printf( "%c", buffer[ idx ] );
  67.       idx = (idx + 1) % BUFSIZE;
  68.     }
  69.     printf( "\n" );
  70.     lineIdx = (_stopIdx + 2) % BUFSIZE;
  71. }
  72.  
  73. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  74.  
  75. __saveds void Server(void)
  76. {
  77.   ULONG signals;
  78.   ULONG serialMask = 0;
  79.   BOOL  status = FALSE;
  80.   BOOL  doPrint = FALSE;
  81.  
  82.     bufIdx = 0;
  83.   
  84.     SerialMPread = (struct MsgPort *)CreatePort(0,0);
  85.     SerialIOread = (struct IOExtSer *)CreateExtIO( SerialMPread, sizeof(struct IOExtSer) );
  86.  
  87.     if ( SerialMPread && SerialIOread )
  88.     {
  89.       SerialIOread->IOSer.io_Device = SerialIOwrite->IOSer.io_Device;
  90.       SerialIOread->IOSer.io_Unit   = SerialIOwrite->IOSer.io_Unit;
  91.       SerialIOread->io_CtlChar      = SerialIOwrite->io_CtlChar;
  92.  
  93.       if ( SerialSetParams( SerialIOread ) != 0 )
  94.       {
  95. //        puts( "Error setting read serial-parameters!\n" );
  96. //        return( FALSE );
  97.         Signal( mainTask, SIGBREAKF_CTRL_F );      // Tell main task that we failed!
  98.       }
  99.       else
  100.       {
  101.         serialMask = (1L << SerialIOread->IOSer.io_Message.mn_ReplyPort->mp_SigBit);
  102.  
  103.         SerialIOread->IOSer.io_Command = CMD_CLEAR;
  104.         SendIO( SerialIOread );
  105.         
  106.         QueueSerRead();
  107.         status = TRUE;
  108.         memset( buffer, 0, sizeof(buffer) );
  109.         Signal( mainTask, SIGBREAKF_CTRL_D );             // Tell main task that we're up and running
  110.       }
  111.     }
  112.     else
  113.       Signal( mainTask, SIGBREAKF_CTRL_F );      // Tell main task that we failed!
  114.     
  115.     do
  116.     {
  117.       signals = Wait( serialMask | SIGBREAKF_CTRL_F | SIGBREAKF_CTRL_E );
  118.       if ( signals & serialMask )
  119.       {
  120.         // We got a byte from the PSX
  121.         
  122.         UBYTE temp, prev;
  123.  
  124.         temp = incoming;
  125.         QueueSerRead();
  126.         
  127.         prev = buffer[ (bufIdx-1) & (BUFSIZE-1) ];
  128.         buffer[ bufIdx ] = temp;
  129.         if ((temp == 'Y') && ((prev == 'Y') || (prev == 0x0d)) )
  130.         {
  131.           Signal( mainTask, SIGBREAKF_CTRL_E );
  132.           w4y = FALSE;
  133.         }
  134.  
  135.         // Wait for '>>'
  136.         
  137.         if ((temp == '>') && (prev == '>'))
  138.           Signal( mainTask, SIGBREAKF_CTRL_D );
  139.  
  140.         // Tell main task to print stuff when we get a whole line
  141.         
  142.         if (doPrint && ((prev == 0x0d) && (temp == 0x0a)))
  143.         {
  144.           stopIdx = (bufIdx-1) % BUFSIZE;
  145.           Signal( mainTask, (1L << printSigNum) );
  146.         }
  147.         
  148.         // Wait for 'binary'
  149.         
  150.         if (w4bin && (temp == 0x0d) && (prev == 'y') && (buffer[(bufIdx-2) & (BUFSIZE-1)] == 'r'))
  151.         {
  152.           Signal( mainTask, SIGBREAKF_CTRL_D );
  153.           w4bin = FALSE;
  154.         }
  155.  
  156.         bufIdx = (bufIdx + 1) % BUFSIZE;
  157.       }
  158.       
  159.       if ( signals & SIGBREAKF_CTRL_E )
  160.       {
  161.         // Main program wants to get notified each time we get a complete line
  162.         
  163.         doPrint = TRUE;      // Turn on sensing for complete line
  164.         lineIdx = bufIdx;    // Mark start of line
  165.       }
  166.       
  167.     } while (!(signals & SIGBREAKF_CTRL_F));
  168.  
  169.     if ( status )
  170.     {
  171.       AbortIO( SerialIOread );
  172.       DeleteExtIO( SerialIOread );
  173.       DeletePort( SerialMPread );
  174.     }
  175.     
  176.     Signal( mainTask, SIGBREAKF_CTRL_D );      // Tell main task that we're done..
  177.  
  178.     Wait(0L);  // Wait for death..
  179. }
  180.  
  181. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  182.  
  183. BOOL InitTask(void)
  184. {
  185.   ULONG signals;
  186.   
  187.     mainTask = FindTask( NULL );
  188.     task = CreateTask( "UploadTask", 2, &Server, STACK_SIZE );
  189.     if (task)
  190.     {
  191.       signals = Wait( SIGBREAKF_CTRL_D | SIGBREAKF_CTRL_F );
  192.       if ( signals & SIGBREAKF_CTRL_F )
  193.         return( FALSE );
  194.       else
  195.         return( TRUE );      
  196.     }
  197.     return( FALSE );
  198. }
  199.  
  200. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  201.  
  202. void FreeTask()
  203. {
  204.   BPTR fh;
  205.   
  206.     Signal( task, SIGBREAKF_CTRL_F );
  207.     Wait( SIGBREAKF_CTRL_D );
  208.     
  209.     if (fh = Open( "T:temp.dat", MODE_NEWFILE))
  210.     {
  211.       Write( fh, buffer, BUFSIZE );
  212.       Close(fh);
  213.     }
  214. }
  215.  
  216. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  217.  
  218. /*
  219.  * NAME
  220.  *   QueueSerRead
  221.  *
  222.  * FUNCTION
  223.  *   Tells the serial device to wait for an incoming header from the PSX
  224.  *
  225.  */
  226.  
  227. void QueueSerRead( void )
  228. {
  229. //    DIAGNOSE( ("QueueSerRead()\n") );
  230.   
  231.     SerialIOread->IOSer.io_Command = CMD_READ;
  232.     SerialIOread->IOSer.io_Length  = 1;
  233.     SerialIOread->IOSer.io_Data    = (APTR)&incoming;
  234.     SendIO( SerialIOread );
  235. }
  236.  
  237. /*
  238.  * NAME
  239.  *   SerialInit
  240.  *
  241.  * FUNCTION
  242.  *   Initializes the serial device and sets the baud rate
  243.  *
  244.  */
  245.  
  246. int SerialSetParams( struct IOExtSer *io )
  247. {
  248.     io->io_ExtFlags = 0;
  249.     io->io_ReadLen  = 8;
  250.     io->io_WriteLen = 8;
  251.     io->io_Baud     = baudRate;
  252.     io->io_BrkTime  = 750000;
  253.     io->io_StopBits = 1;
  254.     io->io_RBufLen  = 4096;
  255.     io->io_SerFlags = SERF_RAD_BOOGIE;
  256.     io->io_TermArray.TermArray0 = 0x51040303;
  257.     io->io_TermArray.TermArray1 = 0x03030303;
  258.     io->IOSer.io_Command = SDCMD_SETPARAMS;
  259.     return( DoIO((struct IORequest *)io) );
  260. }
  261.  
  262. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  263.  
  264. BOOL SerialInit( void )
  265. {
  266.     w4bin = w4y = FALSE;
  267.     
  268.     SerialMPwrite = (struct MsgPort *)CreatePort(0,0);
  269.     SerialIOwrite = (struct IOExtSer *)CreateExtIO( SerialMPwrite, sizeof(struct IOExtSer) );
  270.  
  271.     if ( SerialMPwrite && SerialIOwrite )
  272.     {
  273.       SerialIOwrite->io_SerFlags = 0;    //SERF_SHARED;
  274.       if ( OpenDevice(DEVICE_NAME, UNIT_NUMBER, (struct IORequest *)SerialIOwrite, 0) )
  275.       {
  276.         puts( "Error initializing serial.device!" );
  277.         return( FALSE );
  278.       }
  279.       
  280.       if ( SerialSetParams( SerialIOwrite ) != 0)
  281.       {
  282.         puts( "Error setting write serial-parameters!\n" );
  283.         return( FALSE );
  284.       }
  285.       return( TRUE );      // Success!
  286.     }
  287.     return( FALSE );
  288. }
  289.  
  290. /*
  291.  * NAME
  292.  *   SerialClose
  293.  *
  294.  * FUNCTION
  295.  *   Closes all serial device stuff
  296.  *
  297.  */
  298.  
  299. void SerialClose( void )
  300.     CloseDevice( SerialIOwrite );
  301.     DeleteExtIO( SerialIOwrite );
  302.     DeletePort( SerialMPwrite );
  303. }
  304.  
  305. /*
  306.  * Sends bytes via serial interface
  307.  *
  308.  * Returns when all data has been transfered
  309.  *
  310.  */
  311.  
  312. LONG SerialSend( void *data, LONG len )
  313. {
  314.   #ifdef DEBUGSEND
  315.     LONG i;
  316.     UBYTE *ptr = data;
  317.     
  318.     printf("SerialSend() (%d bytes)\n", len);
  319.     if (len > 16)
  320.     {
  321.       for ( i = 0; i < 16; i++ )
  322.         printf("%02x ", ptr[i]);
  323.       printf("... %02x", ptr[len-1]);    
  324.     }
  325.     else
  326.     {
  327.       for ( i = 0; i < len; i++ )
  328.         printf("%02x ", ptr[i]);
  329.     }
  330.     printf("\n\n");
  331.   #endif
  332.   
  333.     SerialIOwrite->IOSer.io_Command = CMD_WRITE;
  334.     SerialIOwrite->IOSer.io_Length  = len;
  335.     SerialIOwrite->IOSer.io_Data    = (APTR)data;
  336.     DoIO( SerialIOwrite );
  337.     return( len );
  338. }
  339.  
  340. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  341.  
  342.